package ThreadBaseTest;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by yexuan on 2018/3/7.v
 * 房房
 */

class Resource2{
    private String name;
    private int no;
    private boolean flag = false;

    /**
     * JDK1.5中提供了多线程升级解决方案
     * 将同步synchronized替换成了实现Lock操作
     * 将Object中的wait，notify，notifyAll替换了Condition对象
     * 通过lock.newCondition();获取得到condition
     */
    private Lock lock = new ReentrantLock();
    private Condition condition_pro = lock.newCondition();
    private Condition condition_con = lock.newCondition();

    public void set(String name) throws InterruptedException {
        lock.lock();
        try {
            while (flag)
                condition_pro.await();

            this.name = name +"---"+no++;
            System.out.println(Thread.currentThread().getName()+"..生产了...."+this.name);
            this.flag = true;
            condition_con.signalAll(); //唤醒对方
        }finally {
            lock.unlock();
        }
    }

    public void out() throws InterruptedException {
        lock.lock();
        try {
            while (!flag)
                condition_con.await();

            System.out.println(Thread.currentThread().getName() + "..消费了......" + this.name);
            flag = false;
            condition_pro.signalAll();
        }finally {
            lock.unlock();
        }
    }
}

class Producer2 implements Runnable{
    private Resource2 Resource2;

    public Producer2(Resource2 Resource2) {
        this.Resource2 = Resource2;
    }
    @Override
    public void run() {
        while (true){
            try {
                Resource2.set("商品");
            }catch (Exception e){}
        }
    }
}

class Customer2 implements Runnable{

    private Resource2 Resource2;

    public Customer2(Resource2 Resource2) {
        this.Resource2 = Resource2;
    }
    @Override
    public void run() {
        while (true) {
            try {
                Resource2.out();
            } catch (Exception e) {

            }
        }
    }
}

public class ProducerCustomerDemo2 {
    public static void main(String[] args) {
        Resource2 r = new Resource2();

        Producer2 p = new Producer2(r);
        Customer2 c = new Customer2(r);

        Thread t1 = new Thread(p);
        Thread t2 = new Thread(p);
        Thread t3 = new Thread(c);
        Thread t4 = new Thread(c);

        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
}
